﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.NetworkAnalystTools;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.NetworkAnalyst;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataManagementTools;

using Entity;


namespace Utilities
{
    public class CalcBestRoute
    {
        //系统常量
        private const String IN_NA_DATASET = @"E:\VirtualCampus\ArcGlobeData\ZhiMingBuilding\Campus3D\BuildingWay.gdb\Transportation\Transportation_ND";
        private const String IN_STOP_FC = @"E:\VirtualCampus\ArcGlobeData\ZhiMingBuilding\Campus3D\stops.shp";
        private const String IN_COST_FIELD = "length";
        private const String OUT_NALAYER_NAME = "BestRoute";
        private const String OUTPUT_LAYER_DIRECTION = @"E:\data\output\tempSolveLayer.lyr";

        //private const String IN_NA_DATASET = @"E:\VirtualCampus\ArcGlobeData\shp\zm\ZhiMingBuilding.gdb\Transportation\Transportation_ND";
        //private const String IN_STOP_FC = @"E:\VirtualCampus\ArcGlobeData\shp\zm\stops.shp";
        //private const String IN_COST_FIELD = "length";
        //private const String OUT_NALAYER_NAME = "BestRoute";
        //private const String OUTPUT_LAYER_DIRECTION = @"E:\data\output\zhmSolveLayer.lyr";

        public bool excute(out Collection<ERouteNode> nodes)
        {
            
            bool jobSucceed = false;
            Geoprocessor GP = new Geoprocessor();
            MakeRouteLayer routeLayer = new MakeRouteLayer();
            routeLayer.in_network_dataset = IN_NA_DATASET;
            routeLayer.impedance_attribute = IN_COST_FIELD;
            routeLayer.out_network_analysis_layer = OUT_NALAYER_NAME;

            //routeLayer.in_network_dataset = @"E:\data\Network_ND.nd";
            //routeLayer.impedance_attribute = "length";           
            //routeLayer.out_network_analysis_layer="Route2";// = @"E:\VirtualCampus\RouteAnalysis\3DRoutAnalysis\demo\output\OutNALayer.lyr";


            IGeoProcessorResult makeRouteLayerResult = EsriUtility.RunTool(GP, routeLayer, null);
            INALayer naLayer = GP.Open(makeRouteLayerResult.ReturnValue) as INALayer;
            //SaveLayerToDisk(naLayer as ILayer, @"E:\data\output\OutNALayer.lyr");

            //添加位置
            INAContext naContext = naLayer.Context;
            INAClassFieldMap naClassFieldMap = new NAClassFieldMapClass();
            naClassFieldMap.set_MappedField("Name", "Id");
           
            AddLocations addLocation = new AddLocations();
            addLocation.in_network_analysis_layer = makeRouteLayerResult.ReturnValue;
            addLocation.sub_layer = "Stops";            
            addLocation.in_table = IN_STOP_FC;
            addLocation.field_mappings = naClassFieldMap;//这个参数的设定有点问题
            addLocation.search_tolerance = 5000;//这个参数的设定有点问题，有待解决

            IGeoProcessorResult addLocationResult = EsriUtility.RunTool(GP, addLocation, null);
            

            //实现最短路径分析
            Solve solver = new Solve();
            solver.in_network_analysis_layer = addLocationResult.ReturnValue;
            IGeoProcessorResult solveResult = EsriUtility.RunTool(GP, solver, null);
            INALayer solveLayer = GP.Open(addLocationResult.ReturnValue) as INALayer;
            EsriUtility.SaveLayerToDisk(solveLayer as ILayer, OUTPUT_LAYER_DIRECTION);
            //将文件转换成点坐标值
            IFeatureClass routesFC = naContext.NAClasses.get_ItemByName("Routes") as IFeatureClass;
            nodes=GetNodes(routesFC);

            if (makeRouteLayerResult.Status == ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded
                && addLocationResult.Status == ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded
                && solveResult.Status == ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded)
            {
                jobSucceed = true;
            }
            return jobSucceed;
        }

        private Collection<ERouteNode> GetNodes(IFeatureClass routeFC)
        {
            IFeatureCursor pFeatureCursor;
            IFeature lineFeature;            
            IPointCollection pointCollection;
                      
            Collection<ERouteNode> nodes = new Collection<ERouteNode>();

            pFeatureCursor = routeFC.Search(null, false);
            lineFeature = pFeatureCursor.NextFeature();
            pointCollection = lineFeature.Shape as IPointCollection;

           

            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                IPoint point = new PointClass();

                IZAware zAware = point as IZAware;
                zAware.ZAware = true;

                pointCollection.QueryPoint(i, point);
                IPoint poiPrj = EsriUtility.PCS2GCS(point.X, point.Y);
                ERouteNode node = new ERouteNode(poiPrj.X,poiPrj.Y,point.Z);
                nodes.Add(node);
            }
            return nodes; 

        }
        
      

    }
}
